package cn.com.anysdk.redis.demo.service;

import cn.com.anysdk.redis.api.IRedisService;
import cn.com.anysdk.redis.demo.entity.User;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户服务类
 * 演示使用Redis进行用户数据管理
 */
@Service
public class UserService {

    private static final Logger log = LoggerFactory.getLogger(UserService.class);

    private final ObjectMapper objectMapper;

    // 当前使用默认的Redis服务，后续会展示多实例使用
    @Autowired
    private IRedisService redisService;

    /*
     * 未来的多实例使用方式：
     *
     * @Autowired
     * @Qualifier("userRedis")
     * private IRedisService userRedis;
     *
     * @Autowired
     * @Qualifier("cacheRedis")
     * private IRedisService cacheRedis;
     */

    public UserService() {
        this.objectMapper = new ObjectMapper();
        this.objectMapper.registerModule(new JavaTimeModule());
    }

    /**
     * 保存用户信息
     */
    public void saveUser(Long userId, User user) {
        try {
            String userKey = "user:" + userId;
            String userJson = objectMapper.writeValueAsString(user);

            // 存储用户数据
            boolean success = redisService.set(userKey, userJson);
            if (success) {
                log.info("用户信息保存成功: userId={}", userId);

                // 同时缓存用户基本信息
                String cacheKey = "user:cache:" + userId;
                redisService.setEx(cacheKey, userJson, 3600); // 缓存1小时

                // 更新用户状态Hash
                setUserStatus(userId, user.getStatus());
            } else {
                log.error("用户信息保存失败: userId={}", userId);
            }
        } catch (JsonProcessingException e) {
            log.error("用户信息序列化失败: userId={}", userId, e);
            throw new RuntimeException("保存用户失败", e);
        }
    }

    /**
     * 查询用户信息
     */
    public User getUser(Long userId) {
        try {
            String userKey = "user:" + userId;

            // 先从缓存查询
            String cacheKey = "user:cache:" + userId;
            String cachedUser = redisService.get(cacheKey);
            if (cachedUser != null) {
                log.info("从缓存获取用户信息: userId={}", userId);
                return objectMapper.readValue(cachedUser, User.class);
            }

            // 缓存未命中，从主存储查询
            String userJson = redisService.get(userKey);
            if (userJson != null) {
                log.info("从主存储获取用户信息: userId={}", userId);
                User user = objectMapper.readValue(userJson, User.class);

                // 回写缓存
                redisService.setEx(cacheKey, userJson, 3600);
                return user;
            }

            log.warn("用户不存在: userId={}", userId);
            return null;
        } catch (JsonProcessingException e) {
            log.error("用户信息反序列化失败: userId={}", userId, e);
            throw new RuntimeException("获取用户失败", e);
        }
    }

    /**
     * 删除用户信息
     */
    public boolean deleteUser(Long userId) {
        String userKey = "user:" + userId;
        String cacheKey = "user:cache:" + userId;

        // 同时删除主存储和缓存
        boolean deleted1 = redisService.del(userKey);
        boolean deleted2 = redisService.del(cacheKey);

        // 删除用户状态Hash
        String statusKey = "user:status:" + userId;
        redisService.del(statusKey);

        if (deleted1 || deleted2) {
            log.info("用户信息删除成功: userId={}", userId);
            return true;
        }

        log.warn("用户信息删除失败: userId={}", userId);
        return false;
    }

    /**
     * 检查用户是否存在
     */
    public boolean userExists(Long userId) {
        String userKey = "user:" + userId;
        return redisService.exists(userKey);
    }

    /**
     * 批量查询用户信息
     */
    public Map<Long, User> batchGetUsers(List<Long> userIds) {
        Map<Long, User> result = new HashMap<>();

        for (Long userId : userIds) {
            User user = getUser(userId);
            if (user != null) {
                result.put(userId, user);
            }
        }

        return result;
    }

    /**
     * 设置用户状态（使用Hash结构）
     */
    public void setUserStatus(Long userId, String status) {
        String statusKey = "user:status:" + userId;
        redisService.hSet(statusKey, "status", status);
        redisService.hSet(statusKey, "lastActive", String.valueOf(System.currentTimeMillis()));
        redisService.hSet(statusKey, "userId", String.valueOf(userId));

        // 设置过期时间（7天）
        redisService.expire(statusKey, 7 * 24 * 3600);
    }

    /**
     * 获取用户状态
     */
    public String getUserStatus(Long userId) {
        String statusKey = "user:status:" + userId;
        return redisService.hGet(statusKey, "status");
    }

    /**
     * 获取用户完整状态信息
     */
    public Map<String, String> getUserStatusInfo(Long userId) {
        String statusKey = "user:status:" + userId;
        return redisService.hGetAll(statusKey);
    }

    /**
     * 更新用户最后活跃时间
     */
    public void updateUserLastActive(Long userId) {
        String statusKey = "user:status:" + userId;
        if (redisService.exists(statusKey)) {
            redisService.hSet(statusKey, "lastActive", String.valueOf(System.currentTimeMillis()));
            // 延长过期时间
            redisService.expire(statusKey, 7 * 24 * 3600);
        }
    }

    /**
     * 获取用户数量统计
     */
    public long getUserCount() {
        // 这里使用简单的key pattern，生产环境建议使用专门的计数器
        return redisService.keys("user:*").size();
    }
}